/**
 * jims
 */
package com.jims.master.modules.drug.service;

import com.jims.master.common.config.Global;
import com.jims.master.common.data.StringData;
import com.jims.master.common.persistence.BaseEntity;
import com.jims.master.common.persistence.Page;
import com.jims.master.common.service.CrudService;
import com.jims.master.common.utils.StringUtils;
import com.jims.master.modules.drug.dao.*;
import com.jims.master.modules.drug.entity.*;
import com.jims.master.modules.oper.dao.ClinicItemDictDao;
import com.jims.master.modules.oper.dao.ClinicVsChargeDao;
import com.jims.master.modules.oper.dao.PriceListDao;
import com.jims.master.modules.oper.dao.PriceListLogDao;
import com.jims.master.modules.oper.entity.ClinicItemDict;
import com.jims.master.modules.oper.entity.ClinicVsCharge;
import com.jims.master.modules.oper.entity.PriceList;
import com.jims.master.modules.oper.entity.PriceListLog;
import com.jims.master.modules.sys.utils.UserUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 药品价格Service
 *
 * @author CTQ
 * @version 2017-03-02
 */
@Service
@Transactional(readOnly = true)
public class DrugPriceService extends CrudService<DrugPriceDao, DrugPrice> {
    @Autowired
    private PriceListDao priceListDao;
    @Autowired
    private PriceListLogDao priceListLogDao;
    @Autowired
    private DrugDictDao drugDictDao;
    @Autowired
    private DrugPriceLogDao drugPriceLogDao;
    @Autowired
    private DrugNameDictDao drugNameDictDao;
    @Autowired
    private DrugInfoDao drugInfoDao;
    @Autowired
    private DrugStockDao drugStockDao;
    @Autowired
    private ClinicItemDictDao clinicItemDictDao;
    @Autowired
    private ClinicVsChargeDao clinicVsChargeDao;

    public DrugPrice get(String id) {
        return super.get(id);
    }

    public List<DrugPrice> findList(DrugPrice drugPrice) {
        return super.findList(drugPrice);
    }


    /**
     * 查询现行价格
     *
     * @param page
     * @param drugPrice
     * @return
     */
    public Page<DrugPrice> findListPrice(Page<DrugPrice> page, DrugPrice drugPrice) {
        drugPrice.setPage(page);
        page.setList(dao.findListPrice(drugPrice));
        return page;
    }

    /**
     * 查询历史价格
     *
     * @param page
     * @param drugPrice
     * @return
     */

    public Page<DrugPrice> findListPriceLog(Page<DrugPrice> page, DrugPrice drugPrice) {
        drugPrice.setPage(page);
        page.setList(dao.findListPriceLog(drugPrice));
        return page;
    }

    /**
     * 保存药品价格信息
     * @param drugPrice
     * @return
     * @author CTQ
     */
    @Transactional(readOnly = false)
    public int savePrice(DrugPrice drugPrice) {
        int num = 0;
        if (StringUtils.isNotBlank(drugPrice.getId())) {//修改
            /**处理价表**/
            if (StringUtils.isNotBlank(drugPrice.getPriceList().getId())) {
                PriceList pl = priceListDao.get(drugPrice.getPriceList().getId());
                PriceList priceList = handlePriceList(drugPrice, pl);
                priceList.preUpdate();
                priceListDao.update(priceList);
            }
            /**处理药品价格**/
            drugPrice.preUpdate();
            num = dao.update(drugPrice);
            /**一般的修改不处理drug_price_log记录表**/

        } else {//新增
            /**处理价表**/
            PriceList priceList = handlePriceList(drugPrice, new PriceList());
            priceList.preInsert();
            priceListDao.insert(priceList);
            PriceListLog priceListLog = handlePriceListLog(priceList);
            priceListLog.preInsert();
            priceListLogDao.insert(priceListLog);
            /**处理药品价格**/
            drugPrice.setOrgId(UserUtils.getOrgId());
            drugPrice.setPriceList(priceList);
            drugPrice.preInsert();
            drugPrice.setId(priceList.getId());
            num = dao.insert(drugPrice);
            /**药品价格记录**/
            handleDrugPriceLog(drugPrice, priceList);

            //生成clinicItemDict表
            ClinicItemDict clinicItemDict = new ClinicItemDict();
            clinicItemDict.setItemClass(priceList.getItemClass());        // 诊疗项目分类
            clinicItemDict.setItemCode(priceList.getItemCode());        // 诊疗代码
            clinicItemDict.setItemName(priceList.getItemName());        // 诊疗项目名称
            clinicItemDict.setInputCode(priceList.getInputCode());        // 拼音码
            clinicItemDict.setPrice(priceList.getPrice());          //总价
            clinicItemDict.setPreferPrice(priceList.getPreferPrice());    //优惠价格
            clinicItemDict.updateOrgId();
            clinicItemDict.preInsert();
            clinicItemDict.setId(priceList.getId());
            clinicItemDictDao.insert(clinicItemDict);
            //生成clinicVsCharge表
            ClinicVsCharge clinicVsCharge = new ClinicVsCharge();
            clinicVsCharge.setAmount("1");
            clinicVsCharge.setChargeId(priceList.getId());
            clinicVsCharge.setClinicId(clinicItemDict.getId());
            clinicVsCharge.preInsert();
            clinicVsChargeDao.insert(clinicVsCharge);
        }
        return num;
    }

    /**
     * 处理价表-公用方法
     * @param drugPrice
     * @param priceList
     * @return
     * @author CTQ
     */
    private PriceList handlePriceList(DrugPrice drugPrice, PriceList priceList) {
        DrugDict drugDict = new DrugDict();
        String drugId = drugPrice.getDrugInfo().getDrugDict().getId();
        if (StringUtils.isNotBlank(drugId)) {
            drugDict = drugDictDao.get(drugId);
        }
        DrugNameDict drugNameDict = drugNameDictDao.findByDrugCode(drugDict.getDrugCode());
        if (drugNameDict != null) {
            if (StringUtils.isNotBlank(drugNameDict.getDrugIndicator())) {
                if (drugNameDict.getDrugIndicator().equals("2")) {//中药
                    priceList.setItemClass("B");
                } else {//西药
                    priceList.setItemClass("A");
                }
            }
        }
        priceList.setItemName(drugDict.getDrugName());
        priceList.setItemCode(drugDict.getDrugCode());
        priceList.setItemSpec(drugPrice.getPackageSpec());
        priceList.setUnits(drugPrice.getUnits());
        priceList.setInputCode(drugDict.getInputCode());
        priceList.setOrgId(UserUtils.getOrgId());
        priceList.setClassOnMr(drugPrice.getClassOnMr());
        priceList.setClassOnRcpt(drugPrice.getClassOnRcpt());
        priceList.setClassOnReckoning(drugPrice.getClassOnReckoning());
        priceList.setMedicalInsuranceType(drugPrice.getMedicalInsuranceType());
        priceList.setSubjCode(drugPrice.getSubjCode());
        priceList.setStartDate(new Date());
        priceList.setPrice(drugPrice.getRetailPrice());
        priceList.setPreferPrice(drugPrice.getRetailPrice());

        return priceList;
    }

    /**
     * 处理价表日志-公用方法
     * @param priceList
     * @return
     * @author CTQ
     */
    private PriceListLog handlePriceListLog(PriceList priceList) {
        PriceListLog log = new PriceListLog();
        log.setOrgId(priceList.getOrgId());
        log.setInputCode(priceList.getInputCode());
        log.setClassOnMr(priceList.getClassOnMr());
        log.setClassOnRcpt(priceList.getClassOnRcpt());
        log.setClassOnReckoning(priceList.getClassOnReckoning());
        log.setMedicalInsuranceType(priceList.getMedicalInsuranceType());
        log.setIsNer(Global.YES);
        log.setItemClass(priceList.getItemClass());
        log.setItemCode(priceList.getItemCode());
        log.setItemName(priceList.getItemName());
        log.setItemSpec(priceList.getItemSpec());
        log.setPreferPrice(priceList.getPreferPrice());
        log.setPrice(priceList.getPrice());
        log.setPriceId(priceList.getId());
        log.setStartDate(priceList.getStartDate());
        log.setStopDate(priceList.getStopDate());
        log.setSubjCode(priceList.getSubjCode());
        log.setUnits(priceList.getUnits());
        return log;
    }

    /**
     * 药品价格记录--一般的药品修改不调用此方法，调价，停价才处理此表数据-公用方法
     * @param drugPrice
     * @param priceList
     * @author CTQ
     */
    private void handleDrugPriceLog(DrugPrice drugPrice, PriceList priceList) {
        DrugPriceLog drugPriceLog = new DrugPriceLog();
        drugPriceLog.setDrugInfo(drugPrice.getDrugInfo().getId());
        drugPriceLog.setStartDate(drugPrice.getStartDate());
        drugPriceLog.setPackageSpec(drugPrice.getPackageSpec());
        drugPriceLog.setUnits(drugPrice.getUnits());
        drugPriceLog.setSubjCode(drugPrice.getSubjCode());
        drugPriceLog.setOrgId(drugPrice.getOrgId());
        drugPriceLog.setClassOnMr(drugPrice.getClassOnMr());
        drugPriceLog.setClassOnRcpt(drugPrice.getClassOnRcpt());
        drugPriceLog.setClassOnReckoning(drugPrice.getClassOnReckoning());
        drugPriceLog.setMedicalInsuranceType(drugPrice.getMedicalInsuranceType());
        drugPriceLog.setDurgPriceId(drugPrice.getId());
        drugPriceLog.setPriceId(priceList.getId());
        drugPriceLog.setPriceMax(drugPrice.getPriceMax());
        drugPriceLog.setRetailPrice(drugPrice.getRetailPrice());
        drugPriceLog.setTradePrice(drugPrice.getTradePrice());
        drugPriceLog.setStopDate(drugPrice.getStopDate());
        drugPriceLog.setIsNew(Global.YES);
        drugPriceLog.preInsert();
        drugPriceLogDao.insert(drugPriceLog);
    }


    /**
     * 生成药品基本价格
     * @param drugPrice
     * @return
     * @author CTQ
     */
    @Transactional(readOnly = false)
    public int basicPrice(DrugPrice drugPrice) {
        int num = 0;
        if (drugPrice != null) {
            drugPrice = dao.get(drugPrice);
            if (StringUtils.isNotBlank(drugPrice.getPackageSpec())) {
                /**1.判断本条药品价格是否是基本价格**/
                if (drugPrice.getPackageSpec().contains("*")) {
                    DrugInfo drugInfo = drugInfoDao.get(drugPrice.getDrugInfo());
                    /**2.判断基本价格是否已生成**/
                    drugPrice.setPackageSpec(drugInfo.getMinSpec());
                    drugPrice.setUnits(drugInfo.getMinUnits());
                    drugPrice.updateOrgId();
                    List<DrugPrice> list = dao.findByMinSpec(drugPrice);
                    if (list != null && list.size() > 0) {
                        num = -1;//说明基本价格已生成
                    } else {
                        Double number = Double.valueOf(drugInfo.getPackageNum());
                        drugPrice.setTradePrice(drugPrice.getTradePrice() / number);
                        drugPrice.setRetailPrice(drugPrice.getRetailPrice() / number);
                        if(null != drugPrice.getPriceMax()){
                            drugPrice.setPriceMax(drugPrice.getPriceMax() / number);
                        }else{
                            drugPrice.setPriceMax(null);
                        }

                        /**处理价表**/
                        PriceList priceList = handlePriceList(drugPrice, new PriceList());
                        priceList.preInsert();
                        priceListDao.insert(priceList);
                        PriceListLog priceListLog = handlePriceListLog(priceList);
                        priceListLog.preInsert();
                        priceListLogDao.insert(priceListLog);
                        /**处理药品价格**/
                        drugPrice.setPriceList(priceList);
                        drugPrice.preInsert();
                        drugPrice.setId(priceList.getId());
                        num = dao.insert(drugPrice);
                        /**药品价格记录**/
                        handleDrugPriceLog(drugPrice, priceList);
                        //生成clinicItemDict表
                        ClinicItemDict clinicItemDict = new ClinicItemDict();
                        clinicItemDict.setItemClass(priceList.getItemClass());        // 诊疗项目分类
                        clinicItemDict.setItemCode(priceList.getItemCode());        // 诊疗代码
                        clinicItemDict.setItemName(priceList.getItemName());        // 诊疗项目名称
                        clinicItemDict.setInputCode(priceList.getInputCode());        // 拼音码
                        clinicItemDict.setPrice(priceList.getPrice());          //总价
                        clinicItemDict.setPreferPrice(priceList.getPreferPrice());    //优惠价格
                        clinicItemDict.updateOrgId();
                        clinicItemDict.preInsert();
                        clinicItemDict.setId(priceList.getId());
                        clinicItemDictDao.insert(clinicItemDict);
                        //生成clinicVsCharge表
                        ClinicVsCharge clinicVsCharge = new ClinicVsCharge();
                        clinicVsCharge.setAmount("1");
                        clinicVsCharge.setChargeId(priceList.getId());
                        clinicVsCharge.setClinicId(clinicItemDict.getId());
                        clinicVsCharge.preInsert();
                        clinicVsChargeDao.insert(clinicVsCharge);
                    }
                } else {
                    num = 0;
                }
            }
        }
        return num;
    }

    /**
     * 药品价格调价
     * @param drugPrice
     * @return
     * @author zq
     */
    @Transactional(readOnly = false)
    public int savePriceModify(DrugPrice drugPrice) {
        int num = 1;
        //带*为复数的包装，修改价格时同步修改最小包装的价格
//        drugPrice = dao.get(drugPrice);
        DrugInfo drugInfo = drugInfoDao.get(drugPrice.getDrugInfo());

        //判断是不是大包装
        if (drugPrice.getPackageSpec().contains("*")) {

            //获取最小包装的价格
            DrugPrice drugPriceMinSpec = new DrugPrice();
            drugPriceMinSpec.setDrugInfo(drugPrice.getDrugInfo());
            drugPriceMinSpec.setPackageSpec(drugInfo.getMinSpec());
            drugPriceMinSpec.setUnits(drugInfo.getMinUnits());
            drugPriceMinSpec.updateOrgId();
            List<DrugPrice> priceMinSpec = dao.findByMinSpec(drugPriceMinSpec);

            //判断有没有小包装
            if (priceMinSpec.size() == 1) {
                drugPriceMinSpec = priceMinSpec.get(0);
                drugPriceMinSpec.setTradePrice(drugPrice.getTradePrice() / drugInfo.getPackageNum());
                drugPriceMinSpec.setRetailPrice(drugPrice.getRetailPrice() / drugInfo.getPackageNum());
                num = drugPriceModify(drugPrice, drugPriceMinSpec, drugInfo, num);
            }
            DrugPrice drugPriceMaxSpec = dao.get(drugPrice);
            drugPriceMaxSpec.setTradePrice(drugPrice.getTradePrice());
            drugPriceMaxSpec.setRetailPrice(drugPrice.getRetailPrice());
            num = drugPriceModify(drugPrice, drugPriceMaxSpec, drugInfo, num);
        } else {
            DrugPrice drugPriceOld = dao.get(drugPrice);
            drugPriceOld.setTradePrice(drugPrice.getTradePrice());
            drugPriceOld.setRetailPrice(drugPrice.getRetailPrice());
            num = drugPriceModify(drugPrice, drugPriceOld, drugInfo, num);
        }
        return num;
    }

    /**
     * 药品调价方法
     * drugPrice前台修改的价格记录
     * drugPriceModify要修改的价格记录
     * drugInfo要修改的价表对应的drugInfo
     *
     * @author zhuq
     * @update by CTQ at 2017-07-05 08:35:12
     */
    private int drugPriceModify(DrugPrice drugPrice, DrugPrice drugPriceModify, DrugInfo drugInfo, int num) {

        //1.修改drugPrice表
        drugPriceModify.setStartDate(drugPrice.getStartDate());
        drugPriceModify.preUpdate();
        num = num * dao.update(drugPriceModify);
        /**创建定时任务 create by CTQ at 2017-07-09 09:29:51**/
        dao.createEventTask(UserUtils.getOrgId(), DateFormatUtils.format(drugPrice.getStartDate(),"yyyyMMddHHmmss"),DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss"),drugPrice.getId());

        //2.获取drugPriceLog表的记录,然后新增一条，修改一条
        DrugPriceLog drugPriceLogOld = new DrugPriceLog();
        drugPriceLogOld.setDurgPriceId(drugPriceModify.getId());
        drugPriceLogOld = drugPriceLogDao.findByPriceId(drugPriceLogOld).get(0);
        /**2.1修改药品价格日志表，修改价表停止时间及是否最新价表标识**/
        drugPriceLogDao.updateByDrugPriceId(drugPriceModify.getId(),Global.NO,drugPrice.getStartDate());

        /**2.2插入最新药品价格日志，且开始时间为调价后的开始时间**/
        DrugPriceLog drugPriceLogNew = new DrugPriceLog();
        drugPriceLogNew = drugPriceLogOld;
        drugPriceLogNew.setId(null);
        drugPriceLogNew.setRetailPrice(drugPriceModify.getRetailPrice());
        drugPriceLogNew.setTradePrice(drugPriceModify.getTradePrice());
        drugPriceLogNew.setStartDate(drugPrice.getStartDate());
        drugPriceLogNew.setStopDate(drugPrice.getStopDate());
        drugPriceLogNew.setIsNew(Global.YES);
        drugPriceLogNew.preInsert();
        num = num * drugPriceLogDao.insert(drugPriceLogNew);


        //修改priceList表
        PriceList priceList = new PriceList();
        priceList = priceListDao.get(drugPriceModify.getPriceList());
        priceList.setStartDate(drugPriceModify.getStartDate());
        priceList.setPrice(drugPriceModify.getRetailPrice());
        priceList.setPreferPrice(drugPriceModify.getRetailPrice());
        priceList.setStopDate(drugPrice.getStopDate());
        priceList.preUpdate();
        num = num * priceListDao.update(priceList);


        /**update by CTQ**/
        //修改priceListLog表，修改原来的价表的停止时间及是否是最新价表标识，新增一条新开始价表
        PriceListLog priceListLogOld = new PriceListLog();
        priceListLogOld.setPriceId(priceList.getId());
        priceListLogOld = priceListLogDao.findByPriceId(priceListLogOld).get(0);
        /**1.更新price_list_log中id=此记录ID and is_ner='1' and stop_date is null的stop_date和is_ner=0**/
        priceListLogDao.updateByPriceId(priceList.getId(), Global.NO, drugPrice.getStartDate());

        PriceListLog priceListLogNew = new PriceListLog();
        priceListLogNew = priceListLogOld;
        priceListLogNew.setId(null);
        priceListLogNew.setPrice(drugPriceModify.getRetailPrice());
        priceListLogNew.setPreferPrice(drugPriceModify.getTradePrice());
        priceListLogNew.setStartDate(drugPrice.getStartDate());
        priceListLogNew.setStopDate(null);

        /**1:是最新价表0：不是最新价表 add by CTQ at 2017-07-05 09:18:55**/
        priceListLogNew.setIsNer(Global.YES);
        priceListLogNew.preInsert();
        num = num * priceListLogDao.insert(priceListLogNew);


        return num;
    }

    /**
     * 调价时只获取最大包装
     *
     * @author zhuq
     */
    @Transactional(readOnly = false)
    public Page<DrugPrice> findByMaxSpec(Page<DrugPrice> page, DrugPrice drugPrice) {
        drugPrice.updateOrgId();
        drugPrice.setPage(page);
        page.setList(dao.findByMaxSpec(drugPrice));
        return page;
    }

    /**
     * 药品停价功能
     *
     * @param drugPrice
     * @return
     * @author fengyg
     */
    @Transactional(readOnly = false)
    public StringData stopPrice(DrugPrice drugPrice) {
        int i = 0;
        StringData data = new StringData();
        List<DrugPrice> drugPrices = dao.findByDrugInfo(drugPrice);  //大小包装价格
        List<String> priceIds = new ArrayList<String>();    //存放价表price_list的ID
        DrugStock stock = new DrugStock();
        stock.setInfoId(drugPrice.getDrugInfo().getId());
        stock.setOrgId(drugPrice.getOrgId());
        List<DrugStock> stocks = drugStockDao.getList(stock);
        if (null != stocks && stocks.size() > 0) {//有库存，不能停价
            data.setCode("info");
            data.setData("该药品还有库存, 不能停价!!");
        } else {//停价

            if (null != drugPrices && drugPrices.size() > 0) {
                for (DrugPrice price : drugPrices) {
                    Date date = new Date();
                    /**1.判断开始时间是否大于停止时间，如果大于停止时间，则修改开始时间与停止时间一致 add by CTQ at 2017-07-05 10:39:04**/
                    if (price.getStartDate().after(date)){
                        price.setStartDate(date);
                    }
                    price.setStopDate(date);
                    priceIds.add(price.getPriceList().getId());
                    i += dao.update(price);

                    /**2.根据drug_price表的id查询drug_price_log**/
                    DrugPriceLog drugPriceLog = new DrugPriceLog();
                    drugPriceLog.setDurgPriceId(price.getId());
                    /**3.停用药品价表日志记录update by CTQ at 2017-07-05 10:26:20 **/
                    drugPriceLogDao.updateByDrugPriceId(price.getId(),Global.NO,price.getStopDate());

                    /**4 根据drug_price表的price_id查询price_list表数据**/
                    PriceList priceList = new PriceList();
                    priceList.setId(price.getPriceList().getId());
                    PriceList priceList1 = priceListDao.get(priceList);
                    if (null != priceList1) {
                        //设置price_list表的stopDate
                        priceList1.setStopDate(date);
                        priceList1.setDelFlag(BaseEntity.DEL_FLAG_DELETE);
                        i += priceListDao.update(priceList1);

                        /**5.停掉调价记录数据 update by CTQ at 2017-07-05 10:26:20 **/
                        priceListLogDao.updateByPriceId(priceList1.getId(), Global.NO, priceList1.getStopDate());
                    }
                }
            }
            if (i > 0) {
                data.setCode("success");
                data.setData("停价成功!");
            } else {
                data.setCode("error");
                data.setData("停价失败!");
            }
        }
        return data;
    }
    /**
     *  药品价格唯一性验证
     *
     * @param drugPrice
     * @return
     * @author qm;
     */
    @Transactional(readOnly = false)
    public String getNowPrice(DrugPrice drugPrice){
        drugPrice.updateOrgId();
        //根据infoId获取当前价表有没有该价格
        List<DrugPrice> drugPriceList= dao.getNowPriceList(drugPrice);
        if(drugPriceList.size()>0){
            return "false";   //该药品价格已经存在
        }else{
            return "true";   //没有存在
        }
    }
}